﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace LCARS_Interface
{
    public class VlcInterface
    {

        [DllImport("user32.dll")]
        static extern bool PostMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

        [DllImport("user32.dll")]
        static extern bool EnumWindows(EnumWindowsDelegate lpEnumFunc, IntPtr lParam);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool IsWindow(IntPtr hWnd);

        [DllImport("user32.dll")]
        static extern bool IsWindowVisible(IntPtr hWnd);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

        static string GetClassName(IntPtr hwnd)
        {
            string sResult = String.Empty;
            StringBuilder ClassName = new StringBuilder(200);
            //Get the window class name
            int result = GetClassName(hwnd, ClassName, ClassName.Capacity);

            if (result != 0)
            {
                sResult = ClassName.ToString();
            }

            return sResult;
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern int GetWindowTextLength(IntPtr hWnd);

        static string GetWindowText(IntPtr hWnd)
        {
            // Allocate correct string length first
            int length = GetWindowTextLength(hWnd);
            StringBuilder sb = new StringBuilder(length + 1);
            GetWindowText(hWnd, sb, sb.Capacity);
            return sb.ToString();
        }



        public delegate bool EnumWindowsDelegate(IntPtr hWnd, IntPtr lParam);
        

        EnumWindowsDelegate enumWindowsDelegate;
        IntPtr hWndVlc = IntPtr.Zero;


        int WM_APPCOMMAND = 0x0319;

        int APPCOMMAND_VOLUME_MUTE = 8;
        int APPCOMMAND_VOLUME_DOWN = 9;
        int APPCOMMAND_VOLUME_UP = 10;
        int APPCOMMAND_MEDIA_NEXTTRACK = 11;
        int APPCOMMAND_MEDIA_PREVIOUSTRACK = 12;
        int APPCOMMAND_MEDIA_STOP = 13;
        int APPCOMMAND_MEDIA_PLAY_PAUSE = 14;
        int APPCOMMAND_LAUNCH_MEDIA_SELECT = 16;
        int APPCOMMAND_BASS_DOWN = 19;
        int APPCOMMAND_BASS_BOOST = 20;
        int APPCOMMAND_BASS_UP = 21;
        int APPCOMMAND_TREBLE_DOWN = 22;
        int APPCOMMAND_TREBLE_UP = 23;
        int APPCOMMAND_MICROPHONE_VOLUME_MUTE = 24;
        int APPCOMMAND_MICROPHONE_VOLUME_DOWN = 25;
        int APPCOMMAND_MICROPHONE_VOLUME_UP = 26;
        int APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE = 43;
        int APPCOMMAND_MIC_ON_OFF_TOGGLE = 44;
        int APPCOMMAND_MEDIA_PLAY = 46;
        int APPCOMMAND_MEDIA_PAUSE = 47;
        int APPCOMMAND_MEDIA_RECORD = 48;
        int APPCOMMAND_MEDIA_FAST_FORWARD = 49;
        int APPCOMMAND_MEDIA_REWIND = 50;
        int APPCOMMAND_MEDIA_CHANNEL_UP = 51;
        int APPCOMMAND_MEDIA_CHANNEL_DOWN = 52;

        public VlcInterface()
        {
            enumWindowsDelegate = this.EnumWindowsProc;
        }

        IntPtr MakeLParam(int wLow, int wHigh)
        {
            return (IntPtr)((wHigh << 16) | (wLow & 0xffff));
        }

        bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam)
        {
            if (IsWindow(hWnd)
                && GetClassName(hWnd) == "QWidget"
                && GetWindowText(hWnd).Contains("VLC media player"))
            {
                hWndVlc = hWnd;
                return false;
            }

            return true;
        }

        void RefreshVLCHWnd()
        {
            if (hWndVlc == IntPtr.Zero || !IsWindow(hWndVlc))
                EnumWindows(enumWindowsDelegate, IntPtr.Zero);
        }

        public void NextTrack()
        {
            RefreshVLCHWnd();
            PostMessage(hWndVlc, WM_APPCOMMAND, IntPtr.Zero, MakeLParam(0, APPCOMMAND_MEDIA_NEXTTRACK));
        }
        
        public void PreviousTrack()
        {
            RefreshVLCHWnd();
            PostMessage(hWndVlc, WM_APPCOMMAND, IntPtr.Zero, MakeLParam(0, APPCOMMAND_MEDIA_PREVIOUSTRACK));
        }

        public void Stop()
        {
            RefreshVLCHWnd();
            PostMessage(hWndVlc, WM_APPCOMMAND, IntPtr.Zero, MakeLParam(0, APPCOMMAND_MEDIA_STOP));
        }

        public void PlayPause()
        {
            RefreshVLCHWnd();
            PostMessage(hWndVlc, WM_APPCOMMAND, IntPtr.Zero, MakeLParam(0, APPCOMMAND_MEDIA_PLAY_PAUSE));
        }

        public void Play()
        {
            RefreshVLCHWnd();
            PostMessage(hWndVlc, WM_APPCOMMAND, IntPtr.Zero, MakeLParam(0, APPCOMMAND_MEDIA_PLAY));
        }

        public void Pause()
        {
            RefreshVLCHWnd();
            PostMessage(hWndVlc, WM_APPCOMMAND, IntPtr.Zero, MakeLParam(0, APPCOMMAND_MEDIA_PAUSE));
        }

        public void VolumeUp()
        {
            RefreshVLCHWnd();
            PostMessage(hWndVlc, WM_APPCOMMAND, IntPtr.Zero, MakeLParam(0, APPCOMMAND_VOLUME_UP));
        }

        public void VolumeDown()
        {
            RefreshVLCHWnd();
            PostMessage(hWndVlc, WM_APPCOMMAND, IntPtr.Zero, MakeLParam(0, APPCOMMAND_VOLUME_DOWN));
        }

        public void VolumeMute()
        {
            RefreshVLCHWnd();
            PostMessage(hWndVlc, WM_APPCOMMAND, IntPtr.Zero, MakeLParam(0, APPCOMMAND_VOLUME_MUTE));
        }          
    }
}
